package com.gitee.wsl.collections.observable.handler

interface ObservableMapHandler<K, V> {
    fun onClear(elements: Map<K, V>)
    fun onPut(key: K, prevValue: V?, value: V)
    fun onRemove(key: K, value: V)
}

private typealias MapClearBlock<K, V> = (elements: Map<K, V>) -> Unit
private typealias MapPutBlock<K, V> = (key: K, prevValue: V?, value: V) -> Unit
private typealias MapRemoveBlock<K, V> = (key: K, value: V) -> Unit

class ObservableMapHandlerScope<K, V> {
    private var clearBlock: MapClearBlock<K, V>? = null
    private var putBlock: MapPutBlock<K, V>? = null
    private var removeBlock: MapRemoveBlock<K, V>? = null

    fun clear(block: MapClearBlock<K, V>) {
        clearBlock = block
    }

    fun put(block: MapPutBlock<K, V>) {
        putBlock = block
    }

    fun remove(block: MapRemoveBlock<K, V>) {
        removeBlock = block
    }

    private inner class Handler : ObservableMapHandler<K, V> {
        override fun onClear(elements: Map<K, V>) {
            clearBlock?.invoke(elements)
        }

        override fun onPut(key: K, prevValue: V?, value: V) {
            putBlock?.invoke(key, prevValue, value)
        }

        override fun onRemove(key: K, value: V) {
            removeBlock?.invoke(key, value)
        }
    }

    @PublishedApi
    internal fun createHandler(): ObservableMapHandler<K, V> = Handler()
}